;; Copyright (C) 2010  Jon Waltman

;; Author: Jon Waltman <jonathan.waltman@gmail.com>
;; Keywords: reStructuredText rst reST texinfo info

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This package provides the interactive function `rst2texinfo-compile-preview'
;; for quickly viewing the output of running "rst2texinfo" on a buffer
;; visiting a reStructuredText file.

;;; Code:

(require 'rst)
(require 'info)

(defcustom rst2texinfo-run-command "rst2texinfo.py --traceback"
  "*Shell command used to run `rst2texinfo'"
  :type 'string
  :group 'rst2texinfo)



(defun rst2texinfo-current-section ()
  "Return the name of the section containing point, in a rst file."
  (save-excursion
    (unless (car (rst-get-decoration))
      (rst-backward-section)
      (when (bobp)
	(rst-forward-section)))
    (buffer-substring-no-properties (line-beginning-position)
				    (line-end-position))))

(defun rst2texinfo-compilation-sentinel (proc msg)
  (compilation-sentinel proc msg)
  (when (memq (process-status proc) '(signal exit))
    (let (node)
      (if (or (null rst2texinfo-section-name)
	      (string= "" rst2texinfo-section-name))
	  (setq node "Top")
	(with-temp-buffer
	  (insert-file-contents rst2texinfo-file.texi)
	  (goto-char (point-min))
	  (re-search-forward
	   (concat "^@node \\(" (replace-regexp-in-string
				 "[^[:alpha:]]" "." rst2texinfo-section-name)
		   "\\)") nil t)
	  (setq node (or (match-string 1) "Top"))))
      (Info-revert-find-node rst2texinfo-file.info node))))

(defun rst2texinfo-compile-preview (no-query)
  "Compile the current reStructuredText file to Info and view the result.

The Texinfo source is created by invoking the shell command specified by
`rst2texinfo-run-command' with two arguments, the current buffer's filename 
and the name of the output file.  The name of the output file is the same as
the buffer's filename but with the `.texi' extension.

After the Texinfo file is created, the `makeinfo' program is used to generate
the appropriate Info file.

Finally, the current buffer is switched to view the resulting Info file.

With prefix argument `no-query', the current buffer is automatically saved
and no prompts are issued before overwriting existing output files.
"
  (interactive "P")
  (cond ((null buffer-file-name)
	 (error "Buffer not visiting any file"))
	((buffer-modified-p)
	 (when (or no-query
		   (y-or-n-p "Buffer modified; do you want to save it? "))
	   (save-buffer))))
  (let ((src (file-name-sans-extension buffer-file-name)))
    ;; Not local since needed by `rst2texinfo-compilation-sentinel'.
    (setq rst2texinfo-file.texi (concat src ".texi"))
    (setq rst2texinfo-file.info (concat src ".info"))
    (when (and (not no-query)
	       (file-exists-p rst2texinfo-file.texi))
      (unless (y-or-n-p (format "File `%s' exists; over write? " 
                                rst2texinfo-file.texi))
	(error "Canceled")))
    (setq rst2texinfo-section-name (rst2texinfo-current-section))
    (save-excursion
      (let* ((command (concat rst2texinfo-run-command
			      " " (shell-quote-argument buffer-file-name)
			      " " (shell-quote-argument rst2texinfo-file.texi)
			      " && makeinfo -v --no-split -o " 
			      (shell-quote-argument rst2texinfo-file.info)
			      " " (shell-quote-argument rst2texinfo-file.texi)))
	     (buffer (compilation-start command))
	     (process (get-buffer-process buffer)))
	(set-process-sentinel process 'rst2texinfo-compilation-sentinel)))))



(defadvice info-insert-file-contents (after
                                      docutils-info-insert-file-contents
                                      activate)
  "Hack to make `Info-hide-note-references' buffer-local and
automatically set to `hide' iff it can be determined that this file
was created from a Texinfo file generated by Docutils or Sphinx."
  (set (make-local-variable 'Info-hide-note-references)
       (default-value 'Info-hide-note-references))
  (save-excursion
    (save-restriction
      (widen) (goto-char (point-min))
      (when (re-search-forward
             "^Generated by \\(Sphinx\\|Docutils\\)"
             (save-excursion (search-forward "" nil t)) t)
        (set (make-local-variable 'Info-hide-note-references)
             'hide)))))

(provide 'rst2texinfo)
;;; rst2texinfo.el ends here
